package com.jinyijia.api.rest.v1;

import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Maps;
import com.jinyijia.api.rest.v1.dto.UserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author lhw
 * @date 2018/8/18
 **/
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    private static Cache<String, Integer> cache = CacheBuilder.newBuilder()
            .expireAfterWrite(10, TimeUnit.MINUTES)  //写入10分钟后过期
            .maximumSize(100)
            .build();

    @GetMapping("/sms")
    public Object getCategories(String mobile) {
        if (exist(mobile)) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("手机号已注册.");
        }
        Integer code = (int) (Math.random() * 8999) + 1000;
        cache.put("verificationCode" + mobile, code);
        JSONObject object = new JSONObject();
        object.put("phone", mobile);
        object.put("message", "{code:" + code + "}");
        return restTemplate.postForObject("http://sms-service/sms/SMS_118315100", object, Object.class);
    }

    @PostMapping
    public Object register(@Validated @RequestBody UserDTO userDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            Map<String, String> errors = Maps.newHashMap();
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                errors.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
        }
        Integer code = cache.getIfPresent("verificationCode" + userDTO.getMobile());
        if (!userDTO.getVerificationCode().equals(code)) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("验证码错误！");
        }
        return registerUser(userDTO);
    }

    private Object registerUser(UserDTO userDTO) {
        final String username = userDTO.getUsername();
        final String mobile = userDTO.getMobile();
        if (exist(username) || exist(mobile)) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("用户已注册.");
        }
        if (!exitInvitationCode(userDTO.getInvitCode())) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("邀请码已失效");
        }
        Set set = new HashSet();
        set.add("ROLE_USER");
        set.add("ROLE_DISTRIBUTION_CUSTOMER");
        userDTO.setAuthorities(set);
        return restTemplate.postForObject("http://user-service/users", userDTO, Object.class);
    }

    /**
     * 验证用户是否存在
     *
     * @return
     */
    private boolean exist(String name) {
        String url = "http://user-service/users?value=" + name;
        try {
            final Object response = restTemplate.getForObject(url, Object.class);
        } catch (HttpClientErrorException exception) {
            return false;
        }
        return true;
    }

    /**
     * 校验邀请码是否存在
     *
     * @param code
     * @return
     */
    private boolean exitInvitationCode(String code) {
        return restTemplate.getForEntity("http://user-service/users/invitation/code" + "?code=" + code, Boolean.class).getBody();
    }
}
